package cn.itcast.web.controller.system;

import cn.hutool.core.util.StrUtil;
import cn.itcast.domain.commons.ResultInfo;
import cn.itcast.domain.system.Dept;
import cn.itcast.domain.system.Role;
import cn.itcast.domain.system.User;
import cn.itcast.domain.vo.PersonalVo;
import cn.itcast.service.system.DeptService;
import cn.itcast.service.system.RoleService;
import cn.itcast.service.system.UserService;
import cn.itcast.util.ImageUploadUtils;
import cn.itcast.util.MailUtil;
import cn.itcast.util.SmsDemo;
import cn.itcast.web.controller.BaseController;
import com.github.pagehelper.PageInfo;
import org.apache.commons.collections.map.HashedMap;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.xml.transform.Result;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping(value = "/system/user", name = "用户模块")
public class UserController extends BaseController {

    @Autowired
    private UserService userService;

    @Autowired
    private JedisPool jedisPool;

    @RequestMapping(value = "/list", name = "查询用户")
    @RequiresPermissions("用户管理") // 相当于  /system/user/list.do = perms["用户管理"]
    public String list(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "5") Integer pageSize) {
        PageInfo page = userService.findByPage(pageNum, pageSize, getCompanyId());
        request.setAttribute("page", page);
        return "system/user/user-list";
    }

    @Autowired
    private DeptService deptService;

    @RequestMapping(value = "/toAdd", name = "新增页面")
    public String toAdd() {

        // 查询所有部门
        List<Dept> deptList = deptService.findAll(getCompanyId());
        request.setAttribute("deptList", deptList);
        return "system/user/user-add";
    }

    @Autowired
    private AmqpTemplate amqpTemplate;

    @RequestMapping(value = "/edit", name = "新增/修改")
    public String edit(User user) {

        // 拼接邮箱信息
        String to = user.getEmail();
        String title = "Export货代云平台-" + getCompanyName();
        String content = StrUtil.format("{},恭喜您注册成功... <br>访问网址：http://localhost:8080<br>登录邮箱:{},密码：{}", user.getUserName(), user.getEmail(), user.getPassword());;

        // 封装到map集合
        Map map = new HashedMap();
        map.put("to", to);
        map.put("title", title);
        map.put("content", content);

        // 对密码进行加盐加密
        if (StrUtil.isNotEmpty(user.getPassword())) {
            Md5Hash md5Pwd = new Md5Hash(user.getPassword(), user.getEmail(), 2);
            user.setPassword(md5Pwd.toString());
        }

        // 判断用户id是否存在
        if (StrUtil.hasEmpty(user.getId())) {
            // 指定所属企业id和企业名称
            user.setCompanyId(getCompanyId());
            user.setCompanyName(getCompanyName());
            userService.save(user);
            // MailUtil.sendMail(to, title, content);  发送邮件

            // 发送消息
            amqpTemplate.convertAndSend("mail.register", map); // map -- json  -- byte[] 发送

        } else {
            userService.update(user);
        }

        return "redirect:/system/user/list.do";
    }

    @RequestMapping(value = "/toUpdate", name = "修改页面")
    public String toUpdate(String id) {
        // 查询所有部门
        List<Dept> deptList = deptService.findAll(getCompanyId());
        request.setAttribute("deptList", deptList);

        // 根据用户id查询
        User user = userService.findById(id);
        // 将密码设置为null
        user.setPassword(null);
        request.setAttribute("user", user);

        return "system/user/user-update";
    }

    @RequestMapping(value = "/delete", name = "删除")
    public String delete(String id) {
        userService.delete(id);
        return "redirect:/system/user/list.do";
    }

    @Autowired
    private RoleService roleService;

    @RequestMapping(value = "/roleList", name = "进入角色分配页面")
    public String roleList(String id) {
        // 1.显示出用户名称(查询用户信息)
        User user = userService.findById(id);
        request.setAttribute("user", user);

        // 2.显示出所有的角色, 等待勾选( 查询所有角色)
        List<Role> roleList = roleService.findAll(getCompanyId());
        request.setAttribute("roleList", roleList);

        // 3.回显当前用户已经分配了的角色 ( 查询中间表 )
        List<String> roleIdList = userService.findRoleIdListByUserId(id);

        // 将已勾选角色id拼接为字符串，格式为：1,2,3
        String userRoleStr = "";
        for (String roleId : roleIdList) {
            userRoleStr += roleId + ",";
        }
        request.setAttribute("userRoleStr", userRoleStr);

        return "system/user/user-role";
    }

    @RequestMapping(value = "/changeRole", name = "实现用户分配角色")
    public String changeRole(String userId, String[] roleIds) {

        userService.changeRole(userId, roleIds);

        // return "redirect:/system/user/roleList.do?id="+userId;
        return "redirect:/system/user/list.do";
    }



    ////////////////////////////////////杨粤奇///////////////////////////////////////////////////

    @RequestMapping(value = "/toVerify",name = "去往验证页面")
    public String toVerify(){
        return "system/user/verify";
    }

    @RequestMapping(value = "/sendSmsCode", name = "发送验证码")
    @ResponseBody
    public ResultInfo sendSmsCode(String telephone){

        //生成并发送验证码，后面发送是要写在rabbitMQ消费者中进行发送的
        /*
         * 现在要完成的功能是短信通过消息队列RabbitMQ发送
         * 1.生成验证码
         * 2.将手机号和生成的验证码封装到map集合中
         * 3.将验证码存入redis，并设定有效期为5分钟
         * 4.发送消息
         * */
        //1.生成验证码
        String smsCode = SmsDemo.createCode();

        //2.将手机号和生成的验证码封装到map集合中
        Map map = new HashMap();
        map.put("telephone",telephone);
        map.put("smsCode",smsCode);

        //3.将验证码存入redis，有效期为5分钟
        Jedis jedis = jedisPool.getResource();
        jedis.set(telephone,smsCode,"NX","EX",5 * 60);
        System.out.println("您的验证码为："+jedis.get(telephone));

        //4.发送消息
        amqpTemplate.convertAndSend("message.verify",map);

        //返回ResultInfo对象
        return new ResultInfo(true,"验证码发送成功",null);
    }



    @RequestMapping(value = "/verify", name = "验证验证码是否一致")
    public String verify(String telephone, String smsCode){
        //从redis中获取验证码
        Jedis jedis = jedisPool.getResource();
        String redisSmsCode = jedis.get(telephone);
        //取出后立即删除验证码，防止重复登录
        jedis.del(telephone);

        //判断redis中的验证码是否过期，为空则过期
        if (StrUtil.hasEmpty(redisSmsCode)){
            ResultInfo resultInfo = new ResultInfo(false,null,"您的验证码已过期");
            request.setAttribute("resultInfo",resultInfo);
            //用于返回密码找回页面时，电话号码的回显
            request.setAttribute("telephone",telephone);
            return "/system/user/verify";
        }
        //比较两个验证码，如果一致跳转更新数据库密码页面，并返回登录页面，如果不一致重新跳转到密码找回页面
        if (!StrUtil.equals(smsCode,redisSmsCode)){
            ResultInfo resultInfo = new ResultInfo(false,null,"验证码输入错误");
            request.setAttribute("resultInfo",resultInfo);
            //用于返回密码找回页面时，电话号码的回显
            request.setAttribute("telephone",telephone);
            return "/system/user/verify";
        }

        //从数据库中查询电话号对应user是否存在，如果不存在直接跳转
        User user = userService.findByTelephone(telephone);

        if (user == null){
            ResultInfo resultInfo = new ResultInfo(false,null,"手机号不存在，请找管理员添加");
            request.setAttribute("resultInfo",resultInfo);
            return "/system/user/verify";
        }
        //向域中存入用户id
        request.setAttribute("userId",user.getId());
        return "setting/changePw";
    }

    //////////////////////////////////////杨粤奇///////////////////////////////////////////////////////

    //######################################## 余鸿海_start ########################################

    @RequestMapping(path = "/toSetting")
    public String toSetting() {
        request.setAttribute("personal", this.getPersonal());
        return "setting/setting";
    }

    /**
     * 更新个性信息
     * @param personal 个性信息（用户id、昵称、个性宣言，个性图片url为空暂设置）
     * @param icon 个性图像文件
     * @return 转发到个性中心页面
     */
    @RequestMapping(path = "/setting")
    public String setting(PersonalVo personal, MultipartFile icon) {
        boolean imgExist = icon != null && !icon.isEmpty();
        boolean userExist = this.getLoginUser() != null;
        //--------- 图像上传_start ---------
        if ( imgExist && userExist ) {
            // 七牛云工具类进行文件上传
            try {
                String iconUrl = ImageUploadUtils.upload( icon.getInputStream() );
                personal.setIconUrl( iconUrl );
            } catch (IOException e) {
                e.printStackTrace();
                request.setAttribute("msg", "上传失败");
            }
        }
        //--------- 图像上传_end ---------

        userService.updatePersonal(personal);

        session.setAttribute("personal", personal);
        request.setAttribute("msg", "上传成功！");
        //重新刷新会话域中的登陆用户信息
        return "forward:/system/user/toSetting.do";
    }

    /**
     * 更改密码
     * <p>
     * 必须在手机验证之后
     * <ul>
     * <li>用户此时可能并未登陆
     * <li>新密码将加密后直接覆盖旧密码
     * </ul>
     * @param  （用以覆盖旧密码）的新用户
     * @return 成功：转发到主页面的网络请求   失败：重定向登陆界面
     */
    @RequestMapping(path = "/changePw")
    public String changePw(String userId, String password) {

        System.out.println("================changePW.do开始了=======================");
        User user = userService.findById(userId);
        System.out.println("==============="+userId);
        System.out.println(user + "===============");
        // 密码加密
        // 以用户邮箱为“盐”(哈希加密前的明文加密)二次迭代哈希加密
        Md5Hash md5HashPw = new Md5Hash(password,
                user.getEmail(), 2);
        user.setPassword(md5HashPw.toString());

        // 直接覆盖旧密码
        userService.update(user);

       /* //newUser.setPassword(newUser.getPassword().trim());
        // 未登陆状态？   则查询id是否存在
        if (this.getLoginUser() == null) {
            userService.findById(newUser.getId());
            // 查询失败，为了安全，将直接跳转主页，不提示
            return "forward:/login.jsp";
        } else {
            newUser.setId(this.getLoginUser().getId());
            newUser.setEmail(this.getLoginUser().getEmail());
        }
        // 密码加密
        // 以用户邮箱为“盐”(哈希加密前的明文加密)二次迭代哈希加密
        String unencryptedPassword = newUser.getPassword();
        Md5Hash md5HashPw = new Md5Hash(unencryptedPassword,
                this.getLoginUser().getEmail(), 2);
        newUser.setPassword(md5HashPw.toString());

        // 直接覆盖旧密码
        userService.update(newUser);

        request.setAttribute("email", newUser.getEmail());
        request.setAttribute("password", unencryptedPassword);
        return "redirect:/login.do";*/
        return "redirect:/login.jsp";
    }
    //######################################## 余鸿海_end ########################################

}
